import random
import time

from commom import loop_input, clearConsole
from hero import Hero
from prettytable import PrettyTable

from skill import Skill


class Battle:
    def __init__(self, nickname):
        self.hero_name = nickname
        self.coin = 0

    def start(self):
        clearConsole()
        hero = Hero.random_hero(self.hero_name)
        print(hero)
        print('注:【技能名-技能伤害-技能暴击率】')
        while True:
            order = input('输入r【随机属性】/s【开始游戏】/q【返回菜单】:')
            if order == 'r':
                clearConsole()
                hero = Hero.random_hero(self.hero_name)
                print(hero)
                print('注:【技能名-技能伤害-技能暴击率】')
            elif order == 'q':
                return False, 0
            elif order == 's':
                break
            else:
                print('输入错误，请重新输入！')
        clearConsole()
        print(f"\n{self.hero_name}!请前往10层打败魔王！\n")
        for i in range(1, 12):
            if i != 0:
                clearConsole()
            enemy = Hero.random_enemy(i)
            coin = int((enemy.health // 10) * 10 * 1.5)
            print(f'当前位于第{i}层！'.center(20, '*'))
            tb = PrettyTable(['玩家', '属性', 'vs', '敌人', '数据'])
            tb.add_row(['昵称', hero.nickname, '-', '昵称', enemy.nickname])
            tb.add_row(['生命值', hero.health, '-', '生命值', enemy.health])
            tb.add_row(['攻击力', hero.attack, '-', '攻击力', enemy.attack])
            tb.add_row(['护甲值', hero.armor, '-', '护甲值', enemy.armor])
            tb.add_row(['魔能值', hero.mana, '-', '魔能值', enemy.mana])
            tb.add_row(['暴击率', hero.critical, '-', '暴击率', enemy.critical])
            tb.add_row(['技能表', '技能-伤害-暴击率', '-', '技能表', '技能-伤害-暴击率'])
            for j in range(max(len(hero.skills), len(enemy.skills))):
                if j >= len(hero.skills):
                    tb.add_row(['', '', '-', f'技能{j + 1}', enemy.skills[j]])
                elif j >= len(enemy.skills):
                    tb.add_row([f'技能{j + 1}', hero.skills[j], '-', '', ''])
                else:
                    tb.add_row([f'技能{j + 1}', hero.skills[j], '-', f'技能{j + 1}', enemy.skills[j]])
            print(tb)
            order = 'q'
            while order == 'q':
                order = input('按任意按键开始战斗！按Q返回菜单！')
                if order == 'q':
                    if loop_input('确定放弃本局游戏？y/n:', '输入错误', lambda x: x in ['y', 'n']) == 'y':
                        return False, i
            if Battle.fight(hero, enemy):
                if i == 10:
                    print(''.center(20, '*'))
                    print('恭喜你通关10层！'.center(20, '*'))
                    print(''.center(20, '*'))
                    input('按回车继续...')
                    return True, i
                print(f'成功击败 {enemy.nickname},获得 {coin} 金币！ ')
                input('按回车继续...')
                self.coin += coin
                if not self.store(hero, i):
                    return False, i
                continue
            print(f'你战败了,止步于{i}层！请下次加油！')
            input('按回车继续...')
            return False, i

    @staticmethod
    def fight(hero, enemy):
        who_time = bool(random.choice([True, False]))
        print('开始战斗'.center(10, '*'))
        while True:
            print()
            print(f'{hero.nickname}HP【{hero.health}】### {enemy.nickname}HP【{enemy.health}】')

            time.sleep(0.3)
            # 玩家攻击
            if who_time:
                temp = hero
                hero = enemy
                enemy = temp

            is_skill = Battle.chance(hero.mana + len(hero.skills)) if hero.skills else False
            # 使用技能
            if is_skill:
                skill = random.choice(hero.skills)
                is_skill_critical = Battle.chance(skill.critical)
                damage = 2 * skill.damage if is_skill_critical else skill.damage
                damage -= enemy.armor
                damage = 0 if damage <= 0 else damage
                print(
                    f'{hero.nickname}:使用 [{skill.skill_name}] 且 [暴击]  造成 {damage} 伤害' if is_skill_critical else
                    f'{hero.nickname}:使用 [{skill.skill_name}]造成 {damage} 伤害')
            # 普通攻击
            else:
                is_critical = Battle.chance(hero.critical)
                damage = 2 * hero.attack if is_critical else hero.attack
                damage -= enemy.armor
                damage = 0 if damage <= 0 else damage
                print(f'{hero.nickname}: [暴击] 造成 {damage} 伤害' if is_critical else
                      f'{hero.nickname}:造成 {damage} 伤害')
                enemy.health -= damage
                damage = 0 if damage <= 0 else damage
            who_time = not who_time
            if hero.health <= 0:
                print(f'{hero.nickname}HP【0】### {enemy.nickname}HP【{enemy.health}】')
                return False
            if enemy.health <= 0:
                print(f'{hero.nickname}HP【{hero.health}】### {enemy.nickname}HP【0】')
                return True

    def store(self, hero, i):
        tb = PrettyTable(['选项', '功能', '花费'])
        store_list = [
            [1, '增加30生命值', 30 + i],
            [2, '增加5攻击力', 30 + i],
            [3, '增加4护甲值', 30 + i],
            [4, '增加3魔法值', 30 + i],
            [5, '增加2暴击率', 30 + i],
            [6, '获取随机技能', 200],
            [0, '退出商店', 0],
        ]
        tb.add_rows(store_list)
        while True:
            clearConsole()
            print('欢迎来到商店！'.center(20, '*'))
            print('注：魔法值决定释放技能的概率'.center(20, '='))
            print('技能释放几率=（魔法值+技能个数）/100'.center(20, '='))
            print('技能伤害=技能基础伤害*（100+魔力值）/100'.center(20, '='))
            print(tb)
            print(f'当前属性:')
            print(hero)
            print(f'---当前金币:{self.coin}---')
            choice = int(
                loop_input('请输入选项:', '输入错误！', lambda x, n: int(x) in range(n) if x.isdigit() else False, 7))
            if choice == 0:
                break
            elif choice == 1 and self.coin >= store_list[0][2]:
                hero.health += 20
                self.coin -= store_list[0][2]
                print(f'{store_list[0][1]}')
            elif choice == 2 and self.coin >= store_list[1][2]:
                hero.attack += 3
                self.coin -= store_list[1][2]
                print(f'{store_list[1][1]}')
            elif choice == 3 and self.coin >= store_list[2][2]:
                hero.armor += 3
                self.coin -= store_list[2][2]
                print(f'{store_list[2][1]} ')
            elif choice == 4 and self.coin >= store_list[3][2]:
                hero.mana += 3
                self.coin -= store_list[3][2]
                print(f'{store_list[3][1]}')
            elif choice == 5 and self.coin >= store_list[4][2]:
                hero.critical += 3
                self.coin -= store_list[4][2]
                print(f'{store_list[4][1]}')
            elif choice == 6 and self.coin >= store_list[5][2]:
                skill = Skill.random_skill()
                hero.skills.append(skill)
                self.coin -= store_list[5][2]
                print(f'{store_list[5][1]}[{skill}]')
            else:
                print('金币不足！')
            input('按回车继续...')

        order = 'q'
        while order == 'q':
            order = input('按任意按键出发下层！按q返回菜单！')
            if order == 'q':
                if loop_input('确定放弃本局游戏？y/n:', '输入错误', lambda x: x in ['y', 'n']) == 'y':
                    return False
        return True

    @staticmethod
    def chance(num):
        return num >= random.randint(1, 100)
